import os
import xml.etree.ElementTree as ET
from xml.dom import minidom

class ConfigManager:
    """配置管理类，负责读取和保存配置文件"""
    
    def __init__(self):
        """初始化配置管理器"""
        self.config_dir = os.path.join(
            os.environ['USERPROFILE'],
            'AppData', 'Local', 'Firmware_Update_Boot', 'Config'
        )
        self.config_path = os.path.join(self.config_dir, 'Firmware_Update_Boot.cfg')
        
        # 确保配置目录存在
        os.makedirs(self.config_dir, exist_ok=True)
    
    def load_config(self):
        """读取配置文件，返回配置字典"""
        # 如果配置文件不存在，返回默认配置
        if not os.path.exists(self.config_path):
            return self.get_default_config()
        
        try:
            tree = ET.parse(self.config_path)
            root = tree.getroot()
            config = {}
            
            # 解析主窗口尺寸
            main_window = root.find('MainWindow')
            if main_window is not None:
                config['window'] = {
                    'width': int(main_window.get('width', '700')),
                    'height': int(main_window.get('height', '400'))
                }
            
            # 解析杂项配置
            misc = root.find('Miscellaneus')
            if misc is not None:
                config['misc'] = {
                    'logging': int(misc.get('logging', '0')),
                    'log_file': misc.get('log_file', ''),
                    'stay_open': int(misc.get('stay_open', '1'))
                }
            
            # 解析会话配置
            session = root.find('Session')
            if session is not None:
                session_type = session.get('session', 'xcp')
                config['session'] = {'type': session_type}
                
                # XCP会话配置
                if session_type == 'xcp':
                    xcp = session.find('Xcp')
                    if xcp is not None:
                        config['session']['xcp'] = {
                            'seed_key': xcp.get('seed_key', ''),
                            'timeout_t1': int(xcp.get('timeout_t1', '1000')),
                            'timeout_t3': int(xcp.get('timeout_t3', '2000')),
                            'timeout_t4': int(xcp.get('timeout_t4', '10000')),
                            'timeout_t5': int(xcp.get('timeout_t5', '1000')),
                            'timeout_t6': int(xcp.get('timeout_t6', '50')),
                            'timeout_t7': int(xcp.get('timeout_t7', '2000')),
                            'connect_mode': int(xcp.get('connect_mode', '0'))
                        }
            
            # 解析传输层配置
            transport = root.find('Transport')
            if transport is not None:
                transport_type = transport.get('transport', 'xcp_mbrtu')
                config['transport'] = {'type': transport_type}
                
                xcp = transport.find('Xcp')
                if xcp is not None:
                    # RS232配置
                    rs232 = xcp.find('Rs232')
                    if rs232 is not None:
                        config['transport']['rs232'] = {
                            'device': rs232.get('device', 'COM1'),
                            'baudrate': int(rs232.get('baudrate', '57600')),
                            'cstype': int(rs232.get('cstype', '0'))
                        }
                    
                    # Modbus RTU配置
                    mbrtu = xcp.find('MbRtu')
                    if mbrtu is not None:
                        config['transport']['mbrtu'] = {
                            'device': mbrtu.get('device', 'COM3'),
                            'baudrate': int(mbrtu.get('baudrate', '115200')),
                            'parity': int(mbrtu.get('parity', '0')),
                            'stopbits': int(mbrtu.get('stopbits', '1')),
                            'destination_address': int(mbrtu.get('destination_address', '2'))
                        }
                    
                    # CAN配置
                    can = xcp.find('Can')
                    if can is not None:
                        config['transport']['can'] = {
                            'device': can.get('device', 'peak_pcanusb'),
                            'channel': int(can.get('channel', '0')),
                            'baudrate': int(can.get('baudrate', '500000')),
                            'transmit_id': int(can.get('transmit_id', '1639')),
                            'receive_id': int(can.get('receive_id', '2017')),
                            'extended_id': int(can.get('extended_id', '0'))
                        }
                    
                    # TCP/IP配置
                    tcpip = xcp.find('TcpIp')
                    if tcpip is not None:
                        config['transport']['tcpip'] = {
                            'address': tcpip.get('address', '192.168.178.23'),
                            'port': int(tcpip.get('port', '1000'))
                        }
            
            return config
        
        except Exception as e:
            print(f"读取配置文件出错: {str(e)}")
            return self.get_default_config()
    
    def save_config(self, config):
        """保存配置到XML文件"""
        try:
            # 创建根节点
            root = ET.Element('CONFIG')
            
            # 添加主窗口配置
            if 'window' in config:
                main_window = ET.SubElement(root, 'MainWindow')
                main_window.set('width', str(config['window'].get('width', 700)))
                main_window.set('height', str(config['window'].get('height', 400)))
            
            # 添加杂项配置
            if 'misc' in config:
                misc = ET.SubElement(root, 'Miscellaneus')
                misc.set('logging', str(config['misc'].get('logging', 0)))
                misc.set('log_file', config['misc'].get('log_file', ''))
                misc.set('stay_open', str(config['misc'].get('stay_open', 1)))
            
            # 添加会话配置
            if 'session' in config:
                session = ET.SubElement(root, 'Session')
                session.set('session', config['session'].get('type', 'xcp'))
                
                # XCP会话配置
                if config['session'].get('type') == 'xcp' and 'xcp' in config['session']:
                    xcp = ET.SubElement(session, 'Xcp')
                    xcp_config = config['session']['xcp']
                    xcp.set('seed_key', xcp_config.get('seed_key', ''))
                    xcp.set('timeout_t1', str(xcp_config.get('timeout_t1', 1000)))
                    xcp.set('timeout_t3', str(xcp_config.get('timeout_t3', 2000)))
                    xcp.set('timeout_t4', str(xcp_config.get('timeout_t4', 10000)))
                    xcp.set('timeout_t5', str(xcp_config.get('timeout_t5', 1000)))
                    xcp.set('timeout_t6', str(xcp_config.get('timeout_t6', 50)))
                    xcp.set('timeout_t7', str(xcp_config.get('timeout_t7', 2000)))
                    xcp.set('connect_mode', str(xcp_config.get('connect_mode', 0)))
            
            # 添加传输层配置
            if 'transport' in config:
                transport = ET.SubElement(root, 'Transport')
                transport.set('transport', config['transport'].get('type', 'xcp_mbrtu'))
                
                xcp = ET.SubElement(transport, 'Xcp')
                
                # RS232配置
                if 'rs232' in config['transport']:
                    rs232 = ET.SubElement(xcp, 'Rs232')
                    rs232_config = config['transport']['rs232']
                    rs232.set('device', rs232_config.get('device', 'COM1'))
                    rs232.set('baudrate', str(rs232_config.get('baudrate', 57600)))
                    rs232.set('cstype', str(rs232_config.get('cstype', 0)))
                
                # Modbus RTU配置
                if 'mbrtu' in config['transport']:
                    mbrtu = ET.SubElement(xcp, 'MbRtu')
                    mbrtu_config = config['transport']['mbrtu']
                    mbrtu.set('device', mbrtu_config.get('device', 'COM3'))
                    mbrtu.set('baudrate', str(mbrtu_config.get('baudrate', 115200)))
                    mbrtu.set('parity', str(mbrtu_config.get('parity', 0)))
                    mbrtu.set('stopbits', str(mbrtu_config.get('stopbits', 1)))
                    mbrtu.set('destination_address', str(mbrtu_config.get('destination_address', 2)))
                
                # CAN配置
                if 'can' in config['transport']:
                    can = ET.SubElement(xcp, 'Can')
                    can_config = config['transport']['can']
                    can.set('device', can_config.get('device', 'peak_pcanusb'))
                    can.set('channel', str(can_config.get('channel', 0)))
                    can.set('baudrate', str(can_config.get('baudrate', 500000)))
                    can.set('transmit_id', str(can_config.get('transmit_id', 1639)))
                    can.set('receive_id', str(can_config.get('receive_id', 2017)))
                    can.set('extended_id', str(can_config.get('extended_id', 0)))
                
                # TCP/IP配置
                if 'tcpip' in config['transport']:
                    tcpip = ET.SubElement(xcp, 'TcpIp')
                    tcpip_config = config['transport']['tcpip']
                    tcpip.set('address', tcpip_config.get('address', '192.168.178.23'))
                    tcpip.set('port', str(tcpip_config.get('port', 1000)))
            
            # 将XML树转换为格式化的字符串
            rough_string = ET.tostring(root, 'utf-8')
            reparsed = minidom.parseString(rough_string)
            pretty_str = reparsed.toprettyxml(indent="  ")
            
            # 写入文件
            with open(self.config_path, 'w', encoding='utf-8') as f:
                f.write(pretty_str)
            
            return True
        
        except Exception as e:
            print(f"保存配置文件出错: {str(e)}")
            return False
    
    def get_default_config(self):
        """返回默认配置"""
        return {
            'window': {
                'width': 700,
                'height': 400
            },
            'misc': {
                'logging': 0,
                'log_file': '',
                'stay_open': 1
            },
            'session': {
                'type': 'xcp',
                'xcp': {
                    'seed_key': '',
                    'timeout_t1': 1000,
                    'timeout_t3': 2000,
                    'timeout_t4': 10000,
                    'timeout_t5': 1000,
                    'timeout_t6': 50,
                    'timeout_t7': 2000,
                    'connect_mode': 0
                }
            },
            'transport': {
                'type': 'xcp_mbrtu',
                'rs232': {
                    'device': 'COM1',
                    'baudrate': 57600,
                    'cstype': 0
                },
                'mbrtu': {
                    'device': 'COM3',
                    'baudrate': 115200,
                    'parity': 0,
                    'stopbits': 1,
                    'destination_address': 2
                },
                'can': {
                    'device': 'peak_pcanusb',
                    'channel': 0,
                    'baudrate': 500000,
                    'transmit_id': 1639,
                    'receive_id': 2017,
                    'extended_id': 0
                },
                'tcpip': {
                    'address': '192.168.178.23',
                    'port': 1000
                }
            }
        } 